//Flow编辑器生成js文件 creator robinjim  Date：2014-5-09
mxCell.prototype.opertor = null;
mxCell.prototype.stepId = null;
mxCell.prototype.bondFunction = null;
mxCell.prototype.funcId = null;
mxCell.prototype.taskState = null;
mxCell.prototype.transfromId = null;


mxCell.prototype.getStepId = function () {
    return this.stepId;
}
mxCell.prototype.setStepId = function (stepId) {
    this.stepId = stepId;
}
mxCell.prototype.setOperator = function (operator) {
    this.opertor = operator;
}
mxCell.prototype.getOperator = function (stepId) {
    return this.opertor;
}
mxCell.prototype.getBondFunction = function () {
    return this.bondFunction;
};
mxCell.prototype.setBondFunction = function (bondFunction) {
    this.bondFunction = bondFunction;
};
mxCell.prototype.setTransformId = function (transformId) {
    this.transfromId = transformId;
}
mxCell.prototype.getTransformId = function () {
    return this.transfromId;
}
mxGraph.prototype.setTaskState = function (taskState) {
    this.taskState = taskState;
}
mxGraph.prototype.getTaskState = function () {
    return this.taskState;
}
mxCell.prototype.setFunId = function (funcId) {
    this.funcId = funcId;
}
mxCell.prototype.getFunId = function () {
    return this.funcId;
}

var defaultWidth = 48;
var defaultHeigth = 48;
//var glpaper = null;
function isEmpty(data) {
    if (typeof(data) == "undefined" || data == null || data == "null" || data == "")
        return true;
    return false;
}

function postCellConnect(cell, func) {

}

function initStyle(graph) {
    var style = graph.getStylesheet().getDefaultVertexStyle();
    delete style[mxConstants.STYLE_STROKECOLOR]; // transparent
    delete style[mxConstants.STYLE_FILLCOLOR]; // transparent
    delete style[mxConstants.STYLE_STROKECOLOR];
    style[mxConstants.STYLE_SHAPE] = mxConstants.SHAPE_IMAGE;
    //style[mxConstants.STYLE_SHAPE] = mxConstants.SHAPE_LABEL;
    //style[mxConstants.STYLE_STROKECOLOR] = '#000000';
    style[mxConstants.STYLE_FONTCOLOR] = '#000000';
    style[mxConstants.STYLE_IMAGE_WIDTH] = '46';
    style[mxConstants.STYLE_IMAGE_HEIGHT] = '46';
    style[mxConstants.STYLE_SPACING] = '10';
    style[mxConstants.STYLE_VERTICAL_ALIGN] = 'top';
    style[mxConstants.STYLE_INDICATOR_SPACING] = '50';

    style[mxConstants.STYLE_VERTICAL_LABEL_POSITION] = 'bottom';
    style[mxConstants.STYLE_ROUNDED] = true;

    return style;
}
function graphListennerHandler(graph) {
    if (!isEmpty(graph)) {
        keyHandler = new mxKeyHandler(graph);
        rubberband = new mxRubberband(graph);

        //监听delete按钮事件
        keyHandler.bindKey(46, function () {
            var cell = graph.getSelectionCell();
            if (cell != null) {
                var type = cell.getOperator();
                var id = cell.getId();
                var obj = editor.getStepArr().getKeyObject("id", id);

                //editor.getStepArr().removeByKeyValue("id",id);
            }
            graph.removeCells();
        });

        //监听拷贝事件,ctrl+c
        keyHandler.bindControlKey(67, function () {
            mxClipboard.copy(graph);
        });

        //监听粘贴事件,ctrl+v
        keyHandler.bindControlKey(86, function () {
            mxClipboard.paste(graph);
        });

        //元素状态改变的事件
        var linkValidator = function (sender, evt) {
            graph.validateGraph();
        };
        graph.getModel().addListener(mxEvent.CHANGE, linkValidator);
    }
}
function listenerGraphCell(graph) {
    /**
     * 鼠标双击事件
     * */
    graph.dblClick = function (evt, cell) {
        var mxe = new mxEventObject(mxEvent.DOUBLE_CLICK, 'event', evt, 'cell', cell);
        this.fireEvent(mxe);
        if (this.isEnabled() && !mxEvent.isConsumed(evt) && !mxe.isConsumed()) {
            if (typeof(cell) != "undefined") {
                propertiesEdit(cell);
            }
        }
    };

    mxEvent.disableContextMenu(document.body);
    mxRectangleShape.prototype.crisp = true;
    graph.panningHandler.autoExpand = true;
    //鼠标右击事件
    graph.panningHandler.factoryMethod = function (menu, cell, evt) {
        if (!isEmpty(cell)) {
            menu.addItem('重命名', null, function () {
                graph.startEditing(cell);
            });

            menu.addItem('属性编辑', null, function () {
                propertiesEdit(cell);
            });

            menu.addItem('删除', null, function () {
                graph.removeCells();
            });
        }
    };
}
function propertiesEdit(cell) {
    var func = cell.getBondFunction();
    var oper = cell.getOperator();
    var stepid = cell.getStepId();
    var id = cell.getId();
    editor.setSelectStep(stepid);
    eval(func + "('" + id + "')");
}

function isEmpty(data) {
    if (typeof(data) == "undefined" || data == null || data == "null" || data == "")
        return true;
    return false;
}
function init() {
    var modules = document.getElementById("toolbar");
    var pos = 0;
    var style = initStyle(editor.getGraph());
    $.ajax({
        type: "get",
        url: basepath + "resource/flowelements.xml",
        datatype: "xml",
        success: function (xml) {
            var xmlDoc = $.parseXML(xml);
            $xml = $(xmlDoc);
            $xml.find('Element').each(function () {
                var node = $(this);
                var name = node.find("name").text();
                var type = node.find("type").text();
                var imgsrc = basepath + "resources/images/" + node.find("icon").text();
                var moduleUL;
                if (pos % 2 == 0) {
                    var moduleUL = document.createElement("ul");
                }
                var moduleLI = document.createElement("li");
                var linkA = document.createElement("a");
                var imgDesc = document.createElement("img");
                imgDesc.src = imgsrc;
                var tmpstyle = mxUtils.clone(style);
                style[mxConstants.STYLE_IMAGE] = imgsrc;
                graph.getStylesheet().putCellStyle(type, style);

            });
        }

    });
}
function saveflow() {
    alert(editor.getGraphXML());
}
Tw = {};
Tw.Flow = {};
Tw.Flow.Editor = function (ids) {
    this.init(ids);
}

$.extend(Tw.Flow.Editor.prototype, {
    parent: null,
    graph: null,
    width: 0,
    height: 0,
    name: "",
    seed: 0,
    stepparams: new Array(),
    deleteSteps: new Array(),
    selectItemId: null,
    selectedItem: null,
    selectedStep: null,
    startStep: null,
    endStep: null,
    flowId: null,
    id: 0,
    init: function (ids) {
        if (!mxClient.isBrowserSupported()) {
            mxUtils.error('Browser is not supported!', 200, false);
        } else {
            this.graph = new mxGraph(document.getElementById(ids));
            this.graph.setPanning(true);
            this.graph.setTooltips(true);
            this.graph.htmlLabels = true;
            this.graph.setConnectable(true);
            this.graph.setMultigraph(false);
            this.graph.setAllowDanglingEdges(false);
            this.graph.setDropEnabled(true);
            graphListennerHandler(this.graph);
            //listenerGraphCell(this.graph);
            this.initEvent();
        }
    },
    getId: function () {
        this.id++;
        return this.id;
    },
    init1: function (ids, width, height) {
        this.width = width;
        this.height = height;
    },
    getSelectItemId: function () {
        return this.selectItemId;
    },
    setSelectItemId: function (selectItemId) {
        this.selectItemId = selectItemId;
    }, setSelectStep: function (stepId) {
        this.selectedStep = stepId;
    }, getSelectStep: function () {
        return this.selectedStep;
    },
    genId: function (seed) {
        return ++this.seed;
    },
    getGraph: function () {
        return this.graph;
    }, getDeleteSteps: function () {
        return this.deleteSteps;
    },
    drawRect: function (item) {
        var bbox = item.getBBox();
        var step = new Tw.Flow.Step();
        var tmpId = genId();
        step.init(tmpId, bbox);
    },
    drawRectN: function (selectitm, posx, posy) {
        this.selectedItem = selectitm;
        var step = new Tw.Flow.Step(selectitm);
        var tmpId = this.genId();
        return step.initbyPos(tmpId, posx, posy);
    },
    drawImage: function (src, type, title, func, posx, posy) {
        var tmpId = this.genId();
        var step = new Tw.Flow.Step(type, tmpId, title);
        var img = step.drawImage(this.graph, tmpId, type, src, func, posx, posy, defaultWidth, defaultHeigth);
        var arr = {id: img.getId(), type: type, stepId: ''};
        this.stepparams.append(arr);
        return img;
    },
    addVertex: function (type, value, w, h, func) {
        try {
            var style = initStyle(this.graph);
            style[mxConstants.STYLE_IMAGE] = contextpath + "resources/images/" + type + ".png";
            var tmpId = this.genId();
            var step = new Tw.Flow.Step(type, tmpId, value);
            step.addVertex(this.graph, tmpId, type, value, w, h, func);
            return step;
        } finally {

        }
    },
    //初始化工具栏按钮，并可拖拽
    initToolBox: function (img, w, h, value, styleKey, highlightDropTargets, componentId, bindFunction, type) {
        highlightDropTargets = highlightDropTargets == null ? false : highlightDropTargets;
        //var value = null;

        var cell = new mxCell((!isEmpty(value)) ? value : '', new mxGeometry(0, 0, w, h), styleKey);
        cell.vertex = true;
        //绑定自定义属性到组件，这里组件指的是cell
        //cell].setValue(cellValue);
        cell.setOperator(componentId);//组件Id
        cell.setBondFunction(bindFunction);//绑定绑定函数
        //cell.setStepImage(img.src);
        cell.setStyle(styleKey);
        //console.log(cell.getStyle());
        this.addComponentItem(this.graph, cell, img, highlightDropTargets, type);

        img.enabled = true;

        this.graph.getSelectionModel().addListener(mxEvent.CHANGE, function () {
            var tmp = this.graph.isSelectionEmpty();
            mxUtils.setOpacity(img, (true) ? 100 : 20);//设置不透明度
            img.enabled = tmp;
        });

    }, addComponentItem: function (graph, cell, img, highlightDropTargets, type) {
        // 拖拽至画布生成stepID
        // 在给定的位置插入一个元素
        // 如果鼠标点击连接图标并移动到另外一个元素时，就建立两个图标的连接
        var funct = function (graph, evt, target, x, y) {
            console.log('x=' + x + ',y=' + y);
            if (this.getFlowId() == null || this.getFlowId() == undefined) {
                dhtmlx.alert({title: "错误", type: "alert-error", text: "请新建或打开已保存流程"});
                return;
            }
            //isValidDropTarget Returns true if the given cell is a valid drop target for the specified cells // 目标是否有效
            var validDropTarget = (target != null) ?
                graph.isValidDropTarget(target, [cell], evt) : false;
            var style = cell.getStyle();
            var select = null;

            if (target != null && !validDropTarget &&
                graph.getModel().getChildCount(target) == 0 &&
                graph.getModel().isVertex(target) == cell.vertex) {
                graph.getModel().setStyle(target, style);
                select = target;
            }
            else {
                if (target != null && !validDropTarget) {
                    target = null;
                }

                var pt = graph.getPointForEvent(evt);
                select = graph.moveCells([cell], pt.x, pt.y, true, target);
            }
            this.graph.setSelectionCells(select);
        };

        // 创建拖动源的预览
        var dragElt = document.createElement('div');
        dragElt.style.border = 'dashed black 1px';
        dragElt.style.width = '50px';
        dragElt.style.height = '50px';

        // 在点击拖动源图标时提供预览。 预览是提供的仅仅是拖动源的图片
        var ds = mxUtils.makeDraggable(img, graph, funct, dragElt, 0, 0, graph.autoscroll, highlightDropTargets);
        //// 从拖动源拖动时显示导航线
        ds.isGuidesEnabled = function () {
            return this.graph.graphHandler.guidesEnabled;
        };
        // 从拖动源拖动元素到图形以外的区域时，显示拖动源图片预览
        ds.createDragElement = mxDragSource.prototype.createDragElement;
        ds.enabled = !isEmpty(type) ? (type != Etl.task) : true;
    },
    getGraph: function () {
        return this.graph;
    },
    getStepById: function () {

    },
    setFlowId: function (flowId) {
        this.flowId = flowId;
    }, getFlowId: function () {
        return this.flowId;
    },
    setStart: function (itm) {
        if (this.startStep == null) {
            this.startStep = itm;
            return true;
        } else {
            dhtmlx.alert("开始节点已存在");
            return false
        }
    },
    setEnd: function (itm) {
        if (this.endStep == null) {
            this.endStep = itm;
            return true;
        } else {
            dhtmlx.alert("结束节点已存在");
            return false;
        }
    },
    isStartExist: function () {
        return this.startStep != null;
    },
    isEndExist: function () {
        return this.endStep != null;
    }
    , getGraphXML: function () {
        if (!isEmpty(this.graph)) {
            var encoder = new mxCodec();
            var node = encoder.encode(this.graph.getModel());
            var flowXML = mxUtils.getPrettyXml(node, '  ', '', 'state');
            return flowXML;
        }
    },
    getStepArr: function () {
        return this.stepparams;
    },
    removeAllCell: function () {
        if (!isEmpty(this.graph)) {
            this.graph.removeCells(this.graph.getChildVertices(this.graph.getDefaultParent()));
        }
    },
    addListeners: function (item) {
        var onmove = function (dx, dy, x, y, event) {
            if (this.getSelectItemId() == "tbl_cursor") {
                item.attr({
                    x: x - defaultWidth / 2,
                    y: y - defaultHeigth / 2
                });
            }
        }
        var onend = function () {
            this.drawRect(item);
        }
        item.drag(onmove, null, onend);
        item.mouseover(function () {
            if (this.getSelectItemId() == "tb_cursor") {
                item.attr("cursor", "move");
            } else {
                item.attr("cursor", "default");
            }
        });
        item.click(function () {
            drawRect(item);
        });
        if (item.type == "text") {
            item.dblclick(function () {
                var newText = prompt("test", item.attr("text"));
                if (newText) {
                    item.attr("text", newText);
                }
            });
        }
        return item;
    }, initEvent: function () {
        var graph = this.graph;
        graph.dblClick = function (evt, cell) {
            var mxe = new mxEventObject(mxEvent.DOUBLE_CLICK, 'event', evt, 'cell', cell);
            this.fireEvent(mxe);
            if (!mxEvent.isConsumed(evt) && !mxe.isConsumed()) {
                if (typeof(cell) != "undefined" && !isEmpty(cell.getBondFunction())) {
                    propertiesEdit(cell);
                }
            }
        };

        mxEvent.disableContextMenu(document.body);//禁用浏览器自带右键菜单
        mxRectangleShape.prototype.crisp = true;// 去锯齿效果    
        graph.panningHandler.autoExpand = true;// 设置自动扩大鼠标悬停  

        // 覆写右键单击事件  mxPopupMenu
        graph.panningHandler.factoryMethod = function (menu, cell, evt) {
            var taskState = mxGraph.prototype.getTaskState();
            var numOp, opType = mxCell.prototype.getOperator();
            if (!isEmpty(mxCell.prototype.getOperator()))
                numOp = parseInt(mxCell.prototype.getOperator());

            if (!isEmpty(cell)) {//cell不为空，则在组件上右键点击
                //组件ID为-1表示开始环节，而开始环节不可编辑
                if (cell.getBondFunction() == -1) {
                    //do nothing
                } else {

                    /**查看、编辑**/
                    var isEdit = !isEmpty(cell.getBondFunction());//没有绑定方法则不可编辑
                    menu.addItem('编辑', null, function () {
                        propertiesEdit(cell);
                    }, null, null, isEdit && (numOp >= 2));
                    /**重命名**/

                    menu.addItem('重命名', null, function () {
                        graph.startEditing(cell);
                    }, null, null, numOp >= 2);
                    menu.addSeparator();

                    /**任务的停止、运行**/
                    var run2StepText;
                    if (isEmpty(taskState)) {
                        run2StepText = "运行";
                    } else if (taskState == Task.complete) {
                        run2StepText = "运行任务";
                    } else {
                        run2StepText = (taskState != Task.cancel ? '停止任务' : '运行任务');
                    }

                    if (opType != '') {
                        if (numOp >= 2) {//至少具有修改权限
                            menu.addSeparator();
                            menu.addItem('复制（Ctrl+C）', null, function () {
                                copy();
                            });
                            menu.addItem('剪切（Ctrl+X）', null, function () {
                                cut();
                            });
                            menu.addItem('粘贴（Ctrl+V）', null, function () {
                                paste();
                            }, null, null, true);
                            menu.addItem('删除（Delete）', null, function () {
                                del();
                            });
                        }
                    }

                }

            } else {//在组件之外右键点击
                var isShowSave = false;
                var isShowStartOrStop = false;
                switch (flowOp) {
                    case "1":
                        break;
                    case "2":
                    case "3":
                        isShowSave = true;
                        break;
                    case "4":
                    case "5":
                    case "6":
                    case "7":
                        isShowSave = true;
                        isShowStartOrStop = true;
                        break;
                    default:
                        break;
                }
                menu.addItem('打开流程', null, function () {
                    openFlow();
                }, null, null, true);

                menu.addItem('创建流程', null, function () {
                    createFlow();
                }, null, null, true);
                menu.addSeparator();
                menu.addItem('打开任务', null, function () {
                    openTask();
                }, null, null, true);
                if (opType != Etl.task) {
                    menu.addSeparator();
                    menu.addItem('粘贴（Ctrl+V）', null, function () {
                        paste();
                    }, null, null, numOp >= 2);
                }
            }
        }
    }
});
Tw.Flow.Step = function (oper, id, title) {
    this.init(oper, id, title);
}
$.extend(Tw.Flow.Step.prototype, {
    id: null,
    displayname: "",
    isStart: false,
    isEnd: false,
    posx: 0,
    posy: 0,
    height: 0,
    width: 0,
    targetObj: null,
    pairtxt: null,
    operator: "",
    param: "",
    cell: null,
    initialize: function () {

    },
    init: function (operator, id, title) {
        this.operator = operator;
        //this.id=getId();
        this.id = id;
        this.displayname = title;
    },
    initn: function (num, bbox) {
        this.id = num;
        this.posx = bbox.x;
        this.posy = bbox.y;
        this.drawRect(this.posx, this.posy, defaultWidth, defaultHeigth);
    },
    initbyPos: function (num, posx, posy) {
        this.id = num;
        this.posx = posx;
        this.posy = posy;
        this.displayname = "name" + num;
        var rect = this.drawRect(posx, posy, defaultWidth, defaultHeigth);
        return rect;
    },
    getPosx: function () {
        return this.posx;
    },
    setPosx: function (posx) {
        this.posx = posx;
    },
    drawRect: function (fromposx, fromposy, width, height) {
        var id = this.id;
        var st;
        try {
            graph.getModel().beginUpdate();
            var parent = graph.getDefaultParent();
            st = this.paper.insertVertex(parent, id, this.displayname, fromposx, fromposy, width, height);
        } finally {
            graph.getModel().endUpdate();
        }
        return st;
    },
    drawImage: function (graph, tmpId, type, src, func, fromposx, fromposy, width, height) {

        var st;
        try {
            graph.getModel().beginUpdate();
            var parent = graph.getDefaultParent();
            st = graph.insertVertex(parent, tmpId, this.displayname, fromposx, fromposy, width, height, "shape=image;image=" + src);
            st.setOperator(type);
            st.setBondFunction(func);
        } catch (err) {
            alert("ERROR" + err);
        } finally {
            graph.getModel().endUpdate();
        }
        return st;
    },
    addVertex: function (graph, tmpId, type, value, w, h, func) {
        graph.getModel().beginUpdate();
        try {
            var parent = graph.getDefaultParent();
            var id = this.id;
            var src = contextpath + "resources/images/" + type + ".png";
            var style = initStyle(graph);

            style[mxConstants.STYLE_IMAGE] = src;
            //var cell=graph.insertVertex(graph.getDefaultParent(), null, img, w, h, 70, 70);
            var cell = new mxCell('', new mxGeometry(w, h, 48, 48), style);
            cell.setOperator(type);
            cell.setValue(value);
            cell.setBondFunction(func);
            cell.setVertex(true);
            cell.setConnectable(true);
            cell.setOperator(type);
            cell.setBondFunction(func);
            graph.addCell(cell);
            //graph.getModel().setStyle(cell, style);
            //graph.moveCells(cell, w,h);
            //var cells = graph.importCells([cell], w, h, img);
            //graph.addCells([cell], parent, tmpId,cell,img);
            //graph.scrollCellToVisible(cell);
            this.cell = cell;
            return cell;
        } finally {
            graph.getModel().endUpdate();
        }
    },
    dragger: function () {
        this.ox = this.attr("x");
        this.oy = this.attr("y");
        this.animate({
            "fill-opacity": .2
        }, 500);
    },
    onmove: function (dx, dy) {
        var att = {
            x: this.ox + dx,
            y: this.oy + dy
        };
        this.attr(att);
        var id = this.id;
        var pairtxt = glpaper.getById("TEXT_" + id);
        att = {
            x: this.ox + dx + defaultWidth / 2 - 15,
            y: this.oy + dy + defaultHeigth / 2
        };
        pairtxt.attr(att);
    },
    up: function () {
        this.animate({
            "fill-opacity": 0
        }, 500);
    }
});
